using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using RS.DOM.Common;

namespace RS.DOM.Common
{
    public class TextLine : Line
    {
        public TextLine(Context context, string text, bool isMultiply)
            :base(context)
        {
            this.Add(new Token(context, text, isMultiply));
        }

        private void SplitStrings()
        {
            int i = 0;
            while (i < this.Count)
            {
                Token token = this[i];
                if (token.IsMultiply)
                {
                    int startIdx = token.Text.IndexOf("'");
                    if (startIdx >= 0)
                    {
                        string leftText = token.Text.Substring(0, startIdx).Trim();
                        string middleText;
                        string rightText;

                        int endIdx = token.Text.IndexOf("'", startIdx + 1);
                        if (endIdx >= 0)
                        {
                            middleText = token.Text.Substring(startIdx, endIdx - startIdx).Trim();
                            rightText = token.Text.Substring(endIdx + 1).Trim(); 
                        }
                        else
                        {
                            middleText = token.Text.Substring(startIdx).Trim();
                            rightText = "";
                        }
                        
                        this.Remove(token);

                        if (leftText.Length > 0)
                            this.Insert(i++, new Token(this.Context, leftText.ToLower(), true));

                        if (middleText.Length > 0)
                            this.Insert(i++, new Token(this.Context, middleText, false));

                        if (rightText.Length > 0)
                            this.Insert(i++, new Token(this.Context, rightText.ToLower(), true));

                        i = 0;
                        continue;
                    }
                }

                i += 1;
            }
        }

        private void Split(string pattern)
        {
            int i = 0;
            while (i < this.Count)
            {
                Token token = this[i];
                if (token.IsMultiply)
                {
                    Match m = Regex.Match(token.Text, pattern, RegexOptions.IgnoreCase);
                    if (m.Success)
                    {
                        string leftText = token.Text.Substring(0, m.Index).Trim();
                        string middleText = m.Value.Trim();
                        string rightText = token.Text.Substring(m.Index + m.Value.Length).Trim();

                        this.Remove(token);

                        if (leftText.Length > 0)
                            this.Insert(i++, new Token(this.Context, leftText.ToLower(), true));

                        if (middleText.Length > 0)
                            this.Insert(i++, new Token(this.Context, middleText.ToLower(), false));

                        if (rightText.Length > 0)
                            this.Insert(i++, new Token(this.Context, rightText.ToLower(), true));

                        i = 0;
                        continue;
                    }
                }

                i += 1;
            }
        }

        public override void Build()
        {
            this.SplitStrings();

            //split by tokens
            this.Split(@"Group|d\|Agregate|Expression|Len|New|\\|\/|Me|\?\:|Null|\.\/|\<\=|\,\=|\+\=|\=\=|\|\||\![a-zA-Z]+[0-9]*");

            //$,<,>,+,-,*,/,:=,[space],..
            this.Split(@"\&|\^|\||\;|\?|\$|\<|\>|\+|\-|\*|\/|\%|\\=|\s|\.\.|\,|\@|not in|True|False");
            
            //:,=,.,(,),[,],-
            this.Split(@"\:|\=|\.|\(|\)|\[|\]|\-");
            
            for (int i = 0; i < this.Count; i++)
                this[i] = this[i].Build();
        }

        public override Token Execute()
        {
            return null;
        }
    }
}
